In [2]:
import scipy.signal

def plotspec(x, Ts):
    fig = figure()
    ax1 = fig.add_subplot(211)
    ax1.plot(x)
    
    q = fft.fft(x)
    ax2 = fig.add_subplot(212)
    ax2.plot(fft.fftfreq(len(x), Ts), abs(q))

5.11. Based on the AM modulator, build a quadrature modulator.

  1. Examine the effects of phase offsets on the round-trip fidelity.
  2. Examine the effect of frequency offsets on the demodulation.
  3. Confirm that a ±1% phase error in the demodulator corresponds to >1% cross-interference.
In [29]:
def modQM(Ac, m1, m2, fc, phi, Ts):
    time = Ts*len(m1)
    t = linspace(0, time, len(m2))
    
    c = m1*cos(2*pi*fc*t+phi) - m2*sin(2*pi*fc*t+phi)
    
    return Ac*c

def demodQM(v, fc, Ts):
    time = Ts*len(w)
    t = linspace(0, time, len(w))
    
    c1 = cos(2*pi*fc*t)
    c2 = -sin(2*pi*fc*t)
    
    m1high = c1*v
    m2high = c2*v
    
    fbe = [0, 0.05, 0.1, 0.5]
    damps = [1,0]
    fl = 100
    
    b = scipy.signal.remez(fl, fbe, damps)

    m1 = 2*scipy.signal.lfilter(b, 1, m1high)
    m2 = 2*scipy.signal.lfilter(b, 1, m2high)
    
    return (m1,m2)
In [30]:
def QMroundtrip(dphi, df):
    time = 0.3
    Ts = 1.0/10000.0
    t = linspace(Ts, time, time/Ts-1)
    lent = len(t)
    fc = 1000.0
    c = cos(2*pi*fc*t)

    fm = 20.0

    w1 = 5.0/lent*(linspace(1, lent, lent))+cos(2*pi*fm*t)
    w2 = 5.0/lent*(linspace(lent, 1, lent))-cos(2*pi*fm*t)

    #plotspec(w1,Ts)
    #plotspec(w2,Ts)

    v = modQM(1.0, w1, w2, 1000, 0, Ts)
    #plotspec(v, Ts)

    (wp1,wp2) = demodQM(v, 1000, Ts)
    #plotspec(wp1, Ts)
    #plotspec(wp2, Ts)
    plot(wp1)
    plot(w1)
    plot(w2)
    plot(wp2)
    
QMroundtrip(0,0)
In [31]:
for phi in [-pi/2,-pi/4,-pi/8,0, pi/8,pi/4,pi/2]:
    QMroundtrip(phi, 0)
    figure()
<matplotlib.figure.Figure at 0x10540bd10>
In [32]:
for theta in [-100,-10,-1,1,10,100]:
    QMroundtrip(0, theta)
    figure()
<matplotlib.figure.Figure at 0x105462c90>